package globulin;

import jgame.*;
import jgame.platform.JGEngine.*;
import jgame.impl.JGEngineInterface.*;
import java.util.Vector;

/** @author Sean Pavlichek
 */
public class SeekerMissile extends JGObject {
    // Necessary variables

    private JGObject target;
    private Globulin gameScreen;

    /** Basic constructor.
     * @param inputX The starting x of the missle.
     * @param inputY The starting y of the missle.
     * @param parent The game engine.
     */
    public SeekerMissile(double inputX, double inputY, Globulin parent) {
        // String name, boolean unique_id, double x, double y, int collisionID,
        // String gfxName, double xSpeed, double ySpeed
        super("missile", true, inputX, inputY, Globulin.PLAYER_LASER_COLID,
                "seeker_missile", 0, 0);

        gameScreen = parent;

        getTarget();
    }

    /** Overrides the default move command.
     */
    public void move() {
        // If this missle has no target
        if (target == null || !target.isAlive()) {
            this.y -= 5;
            getTarget();
            // If the missle still has a target
        } else {
            // Calculates the 2 sides of the directional triangle
            double xDiff = (target.x - x);
            double yDiff = (target.y - y);
            // Calculates the angle to the target
            double theta = Math.atan2(Math.abs(yDiff), Math.abs(xDiff));

            // If this is on a target
            if (yDiff == 0 && xDiff == 0) {
                this.xspeed = 0;
                this.yspeed = 0;
                // If this is under a target
            } else if (yDiff == 0) {
                // Sets the speed
                this.xspeed = (5 + (0.2 * gameScreen.level));
                this.yspeed = 0;
                // If this is to the side of the target
            } else if (xDiff == 0) {
                // Sets the speed
                this.xspeed = 0;
                this.yspeed = (5 + (0.2 * gameScreen.level));
                // If the x difference is greater than the y distance
            } else if (Math.abs(xDiff) > Math.abs(yDiff)) {
                // Calculates the speed based on distances
                this.xspeed = ((5 + (0.2 * gameScreen.level)) * Math.cos(theta));
                this.yspeed = ((5 + (0.2 * gameScreen.level)) * Math.sin(theta));
                // If the y difference is greater than the x difference
            } else if (Math.abs(xDiff) < Math.abs(yDiff)) {
                // Calculates the speed based on distances
                this.xspeed = ((5 + (0.2 * gameScreen.level)) * Math.cos(theta));
                this.yspeed = ((5 + (0.2 * gameScreen.level)) * Math.sin(theta));
                // If the differences are equal
            } else if (Math.abs(xDiff) == Math.abs(yDiff)) {
                // Calculates the speed based on distances
                this.xspeed = (2.5 + (0.1 * gameScreen.level));
                this.yspeed = (2.5 + (0.1 * gameScreen.level));
            }

            // Determines the x direction to move the missle
            if (xDiff > 0) {
                this.x += xspeed;
            } else {
                this.x -= xspeed;
            }

            // Determines the y direction to move the missle
            if (yDiff > 0) {
                this.y += yspeed;
            } else {
                this.y -= yspeed;
            }
        }

        // If this has passed out of the game screen
        if (this.y < 0 || this.y > gameScreen.getHeight()) {
            this.remove();
        }
    }

    /** Overrides the default hit method.
     * @param obj The object that hit this missle.
     */
    public void hit(JGObject obj) {
        // If the object was an enemy
        if (obj.colid == Globulin.ENEMY_COLID) {
            this.remove();
        }
    }

    /** Gets a new target for the missle.
     */
    private void getTarget() {
        // Stores the potential targets
        Vector<JGObject> potentialTargets = gameScreen.getObjects("enemy", 0, false, null);
        JGObject enemy = null;
        double currTargetDist = 1000;
        // Checks the potential targets
        for (int i = 0; i < potentialTargets.size(); i++) {
            // Stores the ship's position
            double otherX = potentialTargets.get(i).x;
            double otherY = potentialTargets.get(i).y;

            // Calculates the distance to the ship
            double dist = Math.sqrt(Math.pow(x - otherX, 2) + Math.pow(y - otherY, 2));

            // If the ship is closer than the previous target, updates the target
            if (dist < currTargetDist) {
                enemy = potentialTargets.get(i);
                currTargetDist = dist;
            }
        }

        // Sets the target
        target = enemy;
    }
}
